package gene.core;

import gene.core.sound.SoundPlayer;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;


/**
 *
 * @author vinicius
 */
public class Core extends GameCanvas implements Runnable{

    public static Image        _image        = null;
    public static  InputStream   _inputStream  = null;
    public static  String        _string       = null;
    public static  byte[]        _byteArray    = null;
    public static  Graphics      graphics      = null;
    public static  Scene         _screen       = null;
    private static Core          instace       = null;
    public static  GraphicDevice graphicDevice = null;
    public static SoundPlayer filesoundPlayer  = new SoundPlayer();
    //public static TonePlayer  toneSoundPlayer = null;
    private static int fps = 28;
    public int lastFps = 0;
    public int fpsCont = 0;
    public static int color_background = 0x000000;
    public static int FRAME_SKIP = 2;
    public static int LOOP_TIME = 0;
    public static int GLOBAL_TICKS = 0;
    public static int W = 0;
    public static int H = 0;
    /*cellphone key code*/
    public static int KEYCODE_ID_UP = -1;
    public static int KEYCODE_ID_DOWN = -2;
    public static int KEYCODE_ID_LEFT = -3;
    public static int KEYCODE_ID_RIGHT = -4;
    public static int KEYCODE_ID_FIRE = -5;
    public static int KEYCODE_ID_SOFTKEY_LEFT = -6;
    public static int KEYCODE_ID_SOFTKEY_RIGHT = -7;
    /**/
    public final static int STATE_ID_RUNNING = 1;
    public final static int STATE_ID_PAUSED = 2;
    public static int sleep_time = 1000 / fps;
    public static int _KEYS_PRESSED = 0;
    public static boolean GLOBAL_RUNNING = true;
    public static boolean ENABLE_PLAYER_CONTROL = true;
    public static boolean GLOBAL_FULLSCREEN = true;
    public static boolean fire_pressed = false;

    public static boolean bt_pressed_up = false;
    public static boolean bt_pressed_down = false;
    public static boolean bt_pressed_left = false;
    public static boolean bt_pressed_right = false;
    public static boolean bt_pressed_softkey_left = false;
    public static boolean bt_pressed_softkey_right = false;
    public static boolean bt_pressed_1 = false;
    public static boolean bt_pressed_2 = false;
    public static boolean bt_pressed_3 = false;
    public static boolean bt_pressed_4 = false;
    public static boolean bt_pressed_5 = false;
    public static boolean bt_pressed_6 = false;
    public static boolean bt_pressed_7 = false;
    public static boolean bt_pressed_8 = false;
    public static boolean bt_pressed_9 = false;
    public static boolean bt_pressed_0 = false;
    public static boolean bt_pressed_star = false;
    public static boolean bt_pressed_pound = false;
    
    public int coreState = 0;
    public int orientation = -1;
    public int index = 0;
    public int start = 0;
    //private Thread thread = null;
    //private Component list[] = null;

    /**
     * Get the <code>Core</core> reference .
     * @return the class instance
     */
    public static Core getInstance() {
        return instace;
    }

    /**
     * Initialize the engine creating one global reference
     * The width and height need be 128 pixels or more, if the W and H smaller
     * then 128 will be setted with the default device size;
     * @param w width of device screen
     * @param h heigth of device screen
     * @param fullscreen 
     */
    public static Core InitEngine(int w, int h, boolean fullscreen) {
        if (instace == null) {
            instace = new Core(fullscreen, w, h);
        }
    return instace;
    }

    /**
     * Verify if <code>Core</core> has been initialized
     * @return
     */
    public static boolean isInitialized() {
        return instace != null;
    }

    private Core(boolean fullscreen, int w, int h) {

        super(false);
        setFullScreenMode(true);
        GLOBAL_TICKS = 1;
        graphics = getGraphics();
        if(h >= 128 && w >= 128){
        W = w;
        H = h;
        }else{
        W = getWidth();
        H = getHeight();
        }
        graphicDevice = new GraphicDevice(W,H);//.getInstance();
        //instace = this;
        coreState = STATE_ID_RUNNING;
        //thread = new Thread(this);
        //thread.start();

    }

    /**
     * Get the instance to graphics
     * @return
     */
    public Graphics getCoreGraphics() {
        return graphics;
    }

    /*
     * get the sleep milliseconds to system sleep after each loop
     * @return <code> sleep_time</code>

    public static int getSleepTime() {
    return sleep_time;
    }*/

    public int getW() {
        return W;
    }

    public int getH() {
        return H;
    }

    public void setW(int w) {
        W = w;
    }

    public void setH(int h) {
        H = h;
    }

    /**
     * Update the system Time
     */
    public void updateTime() {
        start =(int) System.currentTimeMillis() - start;
        ++GLOBAL_TICKS;
    }

    /**
     * changes the video mode to fullscreen or not and resize the screen size
     * @param w  new screen width
     * @param h new screen height
     * @param fullscreen
     */
    public void setFullScreen(int w, int h, boolean fullscreen) {
        setFullScreenMode(fullscreen);
    }
    /**
     * Force the system close, clear the memory and exit.
     */
    public void exit() {//forca a saida
        GLOBAL_RUNNING = false;

        clearMem();
        System.gc();
        //System.exit(1);

    }

    /**
     * Update the state of pressed keys
     * @param keyCode
     */
    protected void keyPressed(int keyCode) {
            if(keyCode == KEYCODE_ID_UP){
                bt_pressed_up = true;
            }
            if(keyCode == KEYCODE_ID_DOWN) {
                bt_pressed_down = true;
            }
            if(keyCode == KEYCODE_ID_LEFT) {
                bt_pressed_left = true;
            }
            if(keyCode == KEYCODE_ID_RIGHT) {
                bt_pressed_right = true;
            }
            if(keyCode == KEYCODE_ID_FIRE) {
                fire_pressed = true;
            }
            if(keyCode == KEYCODE_ID_SOFTKEY_LEFT) {
                bt_pressed_softkey_left = true;
            }
            if(keyCode == KEYCODE_ID_SOFTKEY_RIGHT) {
                bt_pressed_softkey_right = true;
            }
            if(keyCode == KEY_NUM0) {
                bt_pressed_0 = true;
            }
        if(keyCode == KEY_NUM1) {
                bt_pressed_1 = true;
            }
        if(keyCode == KEY_NUM2) {
                bt_pressed_2 = true;
            }
        if(keyCode == KEY_NUM3) {
                bt_pressed_3 = true;
            }
        if(keyCode == KEY_NUM4) {
                bt_pressed_4 = true;
            }
        if(keyCode == KEY_NUM5) {
                bt_pressed_5 = true;
            }
        if(keyCode == KEY_NUM6) {
                bt_pressed_6 = true;
            }
        if(keyCode == KEY_NUM7) {
                bt_pressed_7 = true;
            }
        if(keyCode == KEY_NUM8) {
                bt_pressed_8 = true;
            }
        if(keyCode == KEY_NUM9) {
                bt_pressed_9 = true;
            }
        if(keyCode == KEY_POUND) {
                bt_pressed_pound = true;
            }
        if(keyCode == KEY_STAR) {
                bt_pressed_star = true;
            }

    }


    /**
     * Update the released keys
     * @param keyCode
     */
    protected void KeyReleased(int keyCode) {
       
        if(keyCode == KEYCODE_ID_UP) {
                bt_pressed_up = false;
            }
          if(keyCode == KEYCODE_ID_DOWN){
                bt_pressed_down = false;
            }
           if(keyCode == KEYCODE_ID_LEFT) {
                bt_pressed_left = false;
            }
            if(keyCode == KEYCODE_ID_RIGHT) {
                bt_pressed_right = false;
            }
            if(keyCode == KEYCODE_ID_FIRE) {
                fire_pressed = false;
            }
            if(keyCode == KEYCODE_ID_SOFTKEY_LEFT) {
                bt_pressed_softkey_left = false;
            }
            if(keyCode == KEYCODE_ID_SOFTKEY_RIGHT) {
                bt_pressed_softkey_right = false;
            }
            if(keyCode == KEY_NUM0) {
                bt_pressed_0 = false;
            }
        if(keyCode == KEY_NUM1) {
                bt_pressed_1 = false;
            }
        if(keyCode == KEY_NUM2) {
                bt_pressed_2 = false;
            }
        if(keyCode == KEY_NUM3) {
                bt_pressed_3 = false;
            }
        if(keyCode == KEY_NUM4) {
                bt_pressed_4 = false;
            }
        if(keyCode == KEY_NUM5) {
                bt_pressed_5 = false;
            }
        if(keyCode == KEY_NUM6) {
                bt_pressed_6 = false;
            }
        if(keyCode == KEY_NUM7) {
                bt_pressed_7 = false;
            }
        if(keyCode == KEY_NUM8) {
                bt_pressed_8 = false;
            }
        if(keyCode == KEY_NUM9) {
                bt_pressed_9 = false;
            }
        if(keyCode == KEY_POUND) {
                bt_pressed_pound = false;
            }
        if(keyCode == KEY_STAR) {
                bt_pressed_star = false;
            }
        
    }

    /**
     * Method to update the keyboard state
     * @param keyCode
     */
    public boolean isKeyPressed(int keyCode) {
        if ((_KEYS_PRESSED & keyCode) != 0) {
            return true;
        }
        return false;
    }

    /**
     *Clear the memory removing all local allocated objects and references,
     */
    public void clearMem() {

        if(_screen!=null){
            _screen.destroy();
            _screen.destroyScene();
            _screen = null;
        }
        if (filesoundPlayer != null) {
            filesoundPlayer.stopMusic();
            filesoundPlayer.destroy();
            filesoundPlayer = null;
        }

        _screen.clear();
        _screen.destroy();
        _image = null;
        _inputStream = null;
        _string = null;
        _byteArray = null;
        instace = null;
    }

    /**
     * Control the program main loop
     */
    public void run() {

        while (STATE_ID_RUNNING == coreState) {

            
            updateTime();

            if (_screen != null) {
                _screen.update();
                _screen.paint();
            }else{
                graphics.setColor(0x00ffffff);
                graphics.drawString("screen null pointer", 0,40, 0);
            }
            graphicDevice.paint();
        }

        clearMem();
    }

    /**
     * Pause the game
     */
    public void pause() {
        _screen.pause();
    }

    /**
     * Resume the game
     */
    public void resume() {
        _screen.resume();
    }

    /**
     * initialize the inner instances of Core
     */
    public void setScreen(Scene screen) {
        _screen = screen;
        coreState = STATE_ID_RUNNING;
    }

    /*
     * Return the current system time
     * @return <code>GLOBAL_TIME</code>
     *
    public long getTime() {
        return GLOBAL_TIME;
    }
    */

    /**
     * Reset to 0 the current global time
     */
    public void stopTime() {
        GLOBAL_TICKS = 0;
    }

    /**
     * get the current screen on <code>Code</code>
     * @return current screen;
     */
    public Scene getCurrentScreen() {
        return _screen;
    }

    /**
     *
     * @param color 0xaarrggbb
     */
    public void setBackgroundColor(int color) {
        color_background = color;
    }

    /**
     *  Make the system sleeps int time millisecs
     * @param time
     */
    public static void sleep(int time) {
        try {
            Thread.sleep(time);
        } catch (Exception e) {
            //e.printStackTrace();
        }
    }

    /**
     * Loads target file
     * @param file <b>String name of file</b>
     * @return InputStream from loaded file
     */
    public static InputStream loadFile(String file) {
        try {
            return file.getClass().getResourceAsStream(file);
        } catch (Exception e) {
            //e.printStackTrace();
        }
        file = null;
        return null;
    }

    public void sync() {
        sleep(sleep_time);
    }

    /**
     * flush the data
     */
    public void flush(){
    flushGraphics();
    }

    /**
     * Load image from file
     * @param file
     * @return
     */
    public static Image loadImage(String file) {
        _image = null;
        try {
            _image = Image.createImage(file.getClass().getResourceAsStream(file));
            file = null;
        } catch (IOException ex) {
            //if mode_debug
            ex.printStackTrace();
        //endif
        }
        return _image;

    }

}
